import { nextTick } from '../common/utils'
import { VantComponent } from '../common/component'
import { commonProps, inputProps, textareaProps } from './props'
VantComponent({
  field: true,
  classes: ['input-class', 'right-icon-class', 'label-class'],
  props: Object.assign(
    Object.assign(Object.assign(Object.assign({}, commonProps), inputProps), textareaProps),
    {
      size: String,
      icon: String,
      label: String,
      error: Boolean,
      center: Boolean,
      isLink: Boolean,
      leftIcon: String,
      rightIcon: String,
      autosize: null,
      required: Boolean,
      iconClass: String,
      clickable: Boolean,
      inputAlign: String,
      customStyle: String,
      errorMessage: String,
      arrowDirection: String,
      showWordLimit: Boolean,
      errorMessageAlign: String,
      readonly: {
        type: Boolean,
        observer: 'setShowClear',
      },
      clearable: {
        type: Boolean,
        observer: 'setShowClear',
      },
      clearTrigger: {
        type: String,
        value: 'focus',
      },
      border: {
        type: Boolean,
        value: true,
      },
      titleWidth: {
        type: String,
        value: '6.2em',
      },
      clearIcon: {
        type: String,
        value: 'clear',
      },
      extraEventParams: {
        type: Boolean,
        value: false,
      },
    },
  ),
  data: {
    focused: false,
    innerValue: '',
    showClear: false,
  },
  created() {
    this.value = this.data.value
    this.setData({ innerValue: this.value })
  },
  methods: {
    formatValue(value) {
      const { maxlength } = this.data
      if (maxlength !== -1 && value.length > maxlength) {
        return value.slice(0, maxlength)
      }
      return value
    },
    onInput(event) {
      const { value = '' } = event.detail || {}
      const formatValue = this.formatValue(value)
      this.value = formatValue
      this.setShowClear()
      return this.emitChange(Object.assign(Object.assign({}, event.detail), { value: formatValue }))
    },
    onFocus(event) {
      this.focused = true
      this.setShowClear()
      this.$emit('focus', event.detail)
    },
    onBlur(event) {
      this.focused = false
      this.setShowClear()
      this.$emit('blur', event.detail)
    },
    onClickIcon() {
      this.$emit('click-icon')
    },
    onClickInput(event) {
      this.$emit('click-input', event.detail)
    },
    onClear() {
      this.setData({ innerValue: '' })
      this.value = ''
      this.setShowClear()
      nextTick(() => {
        this.emitChange({ value: '' })
        this.$emit('clear', '')
      })
    },
    onConfirm(event) {
      const { value = '' } = event.detail || {}
      this.value = value
      this.setShowClear()
      this.$emit('confirm', value)
    },
    setValue(value) {
      this.value = value
      this.setShowClear()
      if (value === '') {
        this.setData({ innerValue: '' })
      }
      this.emitChange({ value })
    },
    onLineChange(event) {
      this.$emit('linechange', event.detail)
    },
    onKeyboardHeightChange(event) {
      this.$emit('keyboardheightchange', event.detail)
    },
    emitChange(detail) {
      const { extraEventParams } = this.data
      this.setData({ value: detail.value })
      let result
      const data = extraEventParams
        ? Object.assign(Object.assign({}, detail), {
            callback: (data) => {
              result = data
            },
          })
        : detail.value
      this.$emit('input', data)
      this.$emit('change', data)
      return result
    },
    setShowClear() {
      const { clearable, readonly, clearTrigger } = this.data
      const { focused, value } = this
      let showClear = false
      if (clearable && !readonly) {
        const hasValue = !!value
        const trigger = clearTrigger === 'always' || (clearTrigger === 'focus' && focused)
        showClear = hasValue && trigger
      }
      this.setData({ showClear })
    },
    noop() {},
  },
})
